<template>
  <el-drawer
    v-model="visible"
    :title="isEdit ? '编辑表配置' : '新增表配置'"
    direction="rtl"
    size="80%"
    :before-close="handleClose"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="rules"
      label-width="120px"
      class="table-config-form"
    >
      <!-- 数据源和表名 -->
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="数据源" prop="datasourceId">
            <el-select v-model="formData.datasourceId" placeholder="请选择数据源" :disabled="isEdit">
              <el-option
                v-for="ds in props.datasources"
                :key="ds.id"
                :label="ds.name"
                :value="ds.id"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="表名" prop="tableName">
            <el-input v-model="formData.tableName" placeholder="请输入表名" :disabled="isEdit" />
          </el-form-item>
        </el-col>
      </el-row>
      
      <!-- 表注释和实体类名 -->
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="表注释" prop="tableComment">
            <el-input v-model="formData.tableComment" placeholder="请输入表注释" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="实体类名" prop="entityName">
            <el-input v-model="formData.entityName" placeholder="请输入实体类名" />
          </el-form-item>
        </el-col>
      </el-row>
      
      <!-- 包名和作者 -->
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="包名" prop="packageName">
            <el-input v-model="formData.packageName" placeholder="请输入包名" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="作者" prop="author">
            <el-input v-model="formData.author" placeholder="请输入作者" />
          </el-form-item>
        </el-col>
      </el-row>
      
      <!-- 生成路径 -->
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="生成路径" prop="generatePath">
            <el-input v-model="formData.generatePath" placeholder="请输入生成路径" />
          </el-form-item>
        </el-col>
      </el-row>
      

      
      <el-divider>字段配置</el-divider>
      
      <!-- 字段操作按钮 -->
      <div class="field-actions" style="margin-bottom: 16px;">
        <el-button type="primary" size="small" @click="addField">新增字段</el-button>
        <el-button type="success" size="small" @click="addCommonFields">添加通用字段</el-button>
        <el-button type="primary" size="small" @click="showImporter">导入字段配置</el-button>
        <el-button type="default" size="small" @click="exportConfig">导出配置</el-button>
      </div>
      
      <el-table :data="formData.columns" border style="width: 100%" max-height="400">
        <el-table-column prop="columnName" label="字段名" width="120">
          <template #default="{ row }">
            <el-input v-model="row.columnName" size="small" placeholder="字段名" />
          </template>
        </el-table-column>
        <el-table-column prop="columnType" label="字段类型" width="120">
          <template #default="{ row }">
            <el-select v-model="row.columnType" size="small" placeholder="选择类型">
              <el-option label="varchar" value="varchar" />
              <el-option label="int" value="int" />
              <el-option label="bigint" value="bigint" />
              <el-option label="decimal" value="decimal" />
              <el-option label="datetime" value="datetime" />
              <el-option label="date" value="date" />
              <el-option label="text" value="text" />
              <el-option label="tinyint" value="tinyint" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="columnLength" label="长度" width="150">
          <template #default="{ row }">
            <el-input-number v-model="row.columnLength" size="small" :min="0" :max="65535" />
          </template>
        </el-table-column>
        <el-table-column prop="columnScale" label="精度" width="150">
          <template #default="{ row }">
            <el-input-number v-model="row.columnScale" size="small" :min="0" :max="30"  />
          </template>
        </el-table-column>
        <el-table-column prop="columnComment" label="字段注释" width="150">
          <template #default="{ row }">
            <el-input v-model="row.columnComment" size="small" placeholder="字段注释" />
          </template>
        </el-table-column>
        <el-table-column prop="javaFieldName" label="Java字段名" width="120">
          <template #default="{ row }">
            <el-input v-model="row.javaFieldName" size="small" placeholder="Java字段名" />
          </template>
        </el-table-column>
        <el-table-column prop="javaFieldType" label="Java类型" width="120">
          <template #default="{ row }">
            <el-select v-model="row.javaFieldType" size="small">
              <el-option label="String" value="String" />
              <el-option label="Integer" value="Integer" />
              <el-option label="Long" value="Long" />
              <el-option label="BigDecimal" value="BigDecimal" />
              <el-option label="LocalDateTime" value="LocalDateTime" />
              <el-option label="LocalDate" value="LocalDate" />
              <el-option label="Boolean" value="Boolean" />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column prop="defaultValue" label="默认值" width="120">
          <template #default="{ row }">
            <el-input v-model="row.defaultValue" size="small" placeholder="默认值" />
          </template>
        </el-table-column>
        <el-table-column label="选项" width="200">
          <template #default="{ row }">
            <el-checkbox v-model="row.isPrimaryKey" size="small">主键</el-checkbox>
            <el-checkbox v-model="row.isAutoIncrement" size="small">自增</el-checkbox>
            <el-checkbox v-model="row.isNullable" size="small">可空</el-checkbox>
          </template>
        </el-table-column>
        <el-table-column label="更多选项" width="180">
          <template #default="{ row }">
            <el-checkbox v-model="row.showInList" size="small">列表显示</el-checkbox>
            <el-checkbox v-model="row.showInForm" size="small">表单显示</el-checkbox>
            <el-checkbox v-model="row.onUpdateCurrentTimestamp" size="small">更新时间戳</el-checkbox>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" fixed="right">
          <template #default="{ row,$index }">
            <el-button v-if="row.columnName!='id'" type="danger" size="small" @click="removeField($index)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    
    <!-- 字段配置导入器 -->
    <FieldConfigImporter 
      v-model="showImporterDialog" 
      @import="handleImport"
    />
    
    <template #footer>
      <div class="drawer-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="loading">保存配置</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts">
import {computed, onMounted, reactive, ref, watch} from 'vue'
import type {FormInstance, FormRules} from 'element-plus'
import {ElMessage, ElMessageBox} from 'element-plus'
import {type CodegenColumnDTO, type CodegenTableDTO, getCommonFields} from '@/api/codegen'
import FieldConfigImporter from './FieldConfigImporter.vue'
import {convertToBackendFormat} from '@/utils/fieldConfigParser'

interface Props {
  modelValue: boolean
  tableData?: CodegenTableDTO
  isEdit?: boolean
  datasources?: any[]
}

const props = withDefaults(defineProps<Props>(), {
  isEdit: false
})

const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  submit: [data: CodegenTableDTO]
}>()

const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const formRef = ref<FormInstance>()
const loading = ref(false)
const commonFields = ref<CodegenColumnDTO[]>([])
const showImporterDialog = ref(false)

const formData = reactive<CodegenTableDTO>({
  id: '',
  datasourceId: '',
  tableName: '',
  tableComment: '',
  entityName: '',
  packageName: 'com.wzh.example',
  generatePath: '/tmp/codegen',
  author: 'wzh',
  columns: [],
  generateController: true,
  generateService: true,
  generateMapper: true,
  generateXml: true
})



const rules: FormRules = {
  datasourceId: [{ required: true, message: '请选择数据源', trigger: 'change' }],
  tableName: [{ required: true, message: '请输入表名', trigger: 'blur' }],
  entityName: [{ required: true, message: '请输入实体类名', trigger: 'blur' }],
  packageName: [{ required: true, message: '请输入包名', trigger: 'blur' }],
  generatePath: [{ required: true, message: '请输入生成路径', trigger: 'blur' }],
  author: [{ required: true, message: '请输入作者', trigger: 'blur' }]
}


// 初始化数据
const initData = async () => {
  try {
    loading.value = true
    // 加载通用字段
    commonFields.value = await getCommonFields()
  } catch (error) {
    ElMessage.error('初始化数据失败')
  } finally {
    loading.value = false
  }
}

// 监听表数据变化
watch(() => props.tableData, (newData) => {
  if (newData) {
    Object.assign(formData, newData)
  } else {
    // 新增模式下，设置默认数据源为第一个
    if (!props.isEdit && props.datasources && props.datasources.length > 0) {
      formData.datasourceId = props.datasources[0].id
    }
  }
}, { immediate: true })

// 监听数据源变化，设置默认值
watch(() => props.datasources, (newDatasources) => {
  if (!props.isEdit && newDatasources && newDatasources.length > 0 && !formData.datasourceId) {
    formData.datasourceId = newDatasources[0].id
  }
}, { immediate: true })

// 字段名转换为Java字段名
const convertToJavaFieldName = (columnName: string): string => {
  if (!columnName) return ''
  return columnName.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())
}

// 包名转换为驼峰命名（首字母小写）
const convertToCamelCase = (packageName: string): string => {
  if (!packageName) return ''
  return packageName
    .split('.')
    .map(part => {
      // 下划线转驼峰，首字母小写
      return part.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())
        .replace(/^[A-Z]/, letter => letter.toLowerCase())
    })
    .filter(part => part.length > 0)
    .join('.')
}

// 类名转换为驼峰命名（首字母大写）
const convertToClassName = (className: string): string => {
  if (!className) return ''
  // 下划线转驼峰，首字母大写
  return className.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())
    .replace(/^[a-z]/, letter => letter.toUpperCase())
}

// 监听字段名变化，自动生成Java字段名
watch(() => formData.columns, (newColumns) => {
  newColumns.forEach(column => {
    if (column.columnName && !column.javaFieldName) {
      column.javaFieldName = convertToJavaFieldName(column.columnName)
    }
  })
}, { deep: true })

// 监听包名变化，自动转换为驼峰命名
watch(() => formData.packageName, (newPackageName) => {
  if (newPackageName) {
    const convertedName = convertToCamelCase(newPackageName)
    if (convertedName !== newPackageName) {
      formData.packageName = convertedName
    }
  }
})

// 监听实体类名变化，自动转换为驼峰命名（首字母大写）
watch(() => formData.entityName, (newEntityName) => {
  if (newEntityName) {
    const convertedName = convertToClassName(newEntityName)
    if (convertedName !== newEntityName) {
      formData.entityName = convertedName
    }
  }
})

const handleClose = () => {
  visible.value = false
}

// 新增字段
const addField = () => {
  const newField: CodegenColumnDTO = {
    columnName: '',
    columnType: 'varchar',
    columnLength: 255,
    columnScale: 0,
    isNullable: true,
    columnComment: '',
    defaultValue: '',
    isPrimaryKey: false,
    isAutoIncrement: false,
    javaFieldType: 'String',
    javaFieldName: '',
    showInList: true,
    showInForm: true,
    showInQuery: false,
    queryType: 'EQ',
    formType: 'input',
    onUpdateCurrentTimestamp: false,
    extra: ''
  }
  formData.columns.push(newField)
}

// 删除字段
const removeField = (index: number) => {
  formData.columns.splice(index, 1)
}

// 添加通用字段
const addCommonFields = async () => {
  try {
    if (commonFields.value.length === 0) {
      commonFields.value = await getCommonFields()
    }
    
    const existingColumnNames = formData.columns.map(col => col.columnName)
    const fieldsToAdd = commonFields.value
      .filter(field => !existingColumnNames.includes(field.columnName))
      .map(field => ({
        columnName: field.columnName,
        columnType: getColumnTypeByJavaType(field.javaFieldType),
        columnLength: getDefaultLength(field.javaFieldType),
        columnScale: 0,
        isNullable: field.isNullable !== false,
        columnComment: field.columnComment,
        defaultValue: field.defaultValue || '',
        isPrimaryKey: field.isPrimaryKey || false,
        isAutoIncrement: field.isAutoIncrement || false,
        javaFieldType: field.javaFieldType,
        javaFieldName: field.javaFieldName,
        showInList: true,
        showInForm: true,
        showInQuery: false,
        queryType: 'EQ',
        formType: 'input',
        onUpdateCurrentTimestamp: field.columnName === 'update_time',
        extra: field.columnName === 'update_time' ? 'on update CURRENT_TIMESTAMP' : ''
      }))
    
    if (fieldsToAdd.length === 0) {
      ElMessage.info('通用字段已存在')
      return
    }
    
    formData.columns.push(...fieldsToAdd)
    ElMessage.success(`已添加 ${fieldsToAdd.length} 个通用字段`)
  } catch (error) {
    console.error('添加通用字段失败:', error)
    ElMessage.error('添加通用字段失败')
  }
}

// 根据Java类型获取对应的数据库字段类型
const getColumnTypeByJavaType = (javaType: string): string => {
  switch (javaType) {
    case 'String': return 'varchar'
    case 'Integer': return 'int'
    case 'Long': return 'bigint'
    case 'BigDecimal': return 'decimal'
    case 'LocalDateTime': return 'datetime'
    case 'LocalDate': return 'date'
    case 'Boolean': return 'tinyint'
    default: return 'varchar'
  }
}

// 根据Java类型获取默认长度
const getDefaultLength = (javaType: string): number => {
  switch (javaType) {
    case 'String': return 255
    case 'Integer': return 11
    case 'Long': return 20
    case 'BigDecimal': return 10
    case 'Boolean': return 1
    default: return 255
  }
}

// 校验重复字段
const validateDuplicateFields = (): boolean => {
  const columnNames = formData.columns.map(col => col.columnName.toLowerCase())
  const duplicates = columnNames.filter((name, index) => 
    name && columnNames.indexOf(name) !== index
  )
  
  if (duplicates.length > 0) {
    ElMessage.error(`存在重复字段: ${duplicates.join(', ')}`)
    return false
  }
  return true
}

const handleSubmit = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    
    // 校验重复字段
    if (!validateDuplicateFields()) {
      return
    }
    
    loading.value = true
    emit('submit', { ...formData })
    ElMessage.success(props.isEdit ? '更新成功' : '创建成功')
    handleClose()
  } catch (error) {
    console.error('表单验证失败:', error)
  } finally {
    loading.value = false
  }
}

// 显示导入器
const showImporter = () => {
  showImporterDialog.value = true
}

// 处理字段配置导入
const handleImport = (importedFields: CodegenColumnDTO[]) => {
  ElMessageBox.confirm(
    `即将导入 ${importedFields.length} 个字段配置，这将替换当前所有字段配置。是否继续？`,
    '确认导入',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    formData.columns = [...importedFields]
    ElMessage.success(`成功导入 ${importedFields.length} 个字段配置`)
  }).catch(() => {
    ElMessage.info('已取消导入')
  })
}

// 导出字段配置
const exportConfig = () => {
  if (formData.columns.length === 0) {
    ElMessage.warning('没有字段配置可导出')
    return
  }
  
  try {
    // 转换为后台格式
    const backendFormat = convertToBackendFormat(formData.columns)
    const jsonString = JSON.stringify(backendFormat, null, 2)
    
    // 创建下载链接
    const blob = new Blob([jsonString], { type: 'application/json' })
    const url = URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `${formData.tableName || 'table'}_field_config.json`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    URL.revokeObjectURL(url)
    
    ElMessage.success('字段配置导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('字段配置导出失败')
  }
}

// 生命周期
onMounted(() => {
  initData()
})
</script>

<style scoped>
.table-config-form {
  padding: 0 20px;
}

.field-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.drawer-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 20px;
  border-top: 1px solid #e4e7ed;
}

:deep(.el-drawer__body) {
  padding: 20px 0;
}

:deep(.el-table) {
  font-size: 12px;
}

:deep(.el-table .el-table__cell) {
  padding: 8px 0;
}

:deep(.el-checkbox) {
  margin-right: 8px;
  margin-bottom: 4px;
}

:deep(.el-input--small) {
  font-size: 12px;
}

:deep(.el-select--small) {
  font-size: 12px;
}

:deep(.el-button--small) {
  padding: 4px 8px;
  font-size: 12px;
}
</style>